#pragma once

#include <base.h>

/* llsc的汇编实现 */
typedef word_t		llword_t;
typedef struct
{
	union{
		llword_t val;
		word_t rval;
	};
	llword_t *ptr;
} llsc_t;


static inline word_t __ld_link_acq(llword_t *ptr)
{
	word_t val;
	asm volatile(	"	prfm	pstl1strm, %1	\n"
			"	ldaxr	%0, %1		\n"
			: "=&r"(val), "+Q"(*ptr)
			:
			: "memory");
	return val;
}
static inline word_t __ld_link(llword_t *ptr)
{
	word_t val;
	asm volatile(	"	prfm	pstl1strm, %1		\n"
			"	ldxr	%0, %1			\n"
			: "=&r"(val), "+Q"(*ptr)
			:
			: "memory");
	return val;
}
static inline bool_t __st_cond_rel(llword_t *ptr, word_t new_val){
	bool_t result;
	asm volatile("	stlxr	%w0, %2, %1\n"
	: "=&r"(result), "+Q"(*(ptr))
	: "r"(new_val)
	: "memory");
	return result;
}
static inline bool_t __st_cond(llword_t *ptr, word_t new_val){
	bool_t result;
	asm volatile("	stxr	%w0, %2, %1\n"
	: "=&r"(result), "+Q"(*(ptr))
	: "r"(new_val)
	: "memory");
	return result;
}

//接口
static inline word_t ld_link(llsc_t *x, llword_t *ptr)
{
	x->ptr = ptr;
	x->val = __ld_link(ptr);
	return x->val;
}

static inline word_t ld_link_acq(llsc_t *x, llword_t *ptr)
{
	x->ptr = ptr;
	x->val = __ld_link_acq(ptr);

	return x->val;
}

static inline bool_t st_cond_rel(llsc_t *x, word_t new_val)
{
	// int result;
	// // cmb();
	// asm volatile( //"	stlxr	%w0, %2, %1\n"
	// 	"	stlxr	%w0, %2, %1\n"
	// 	: "=&r"(result), "+Q"(*(x->ptr))
	// 	: "r"(new_val)
	// 	: "memory");
	
	bool_t res = __st_cond_rel(x->ptr, new_val);

	if (res){
		/* 失败了重新读取 */
		x->val = __ld_link_acq(x->ptr);
	}
	return !res;
}

static inline bool_t st_cond(llsc_t *x, word_t new_val)
{
	// int result;
	// // cmb();
	// asm volatile( //"	stlxr	%w0, %2, %1\n"
	// 	"	stxr	%w0, %2, %1\n"
	// 	: "=&r"(result), "+Q"(*(x->ptr))
	// 	: "r"(new_val)
	// 	: "memory");
	// //: "cl"	  );
	// // cmb();
	bool_t res = __st_cond(x->ptr, new_val);
	if (res){
		/* 失败了重新读取 */
		x->val = __ld_link(x->ptr);
	}
	return !res;
}



